﻿using AutoMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Project.Common.Jwt;
using Project.Common.MD5;
using Project.DTO;
using Project.IService;
using Project.Models;
using Project.WebAPI.Filters;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Project.WebAPI.Controllers
{
    /// <summary>
    /// 雇主
    /// </summary>
    [Authorize]
    [ApiResultFilter]
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : ControllerBase
    {
        private readonly IConfiguration configuration;
        private readonly IWebUserService userService;
        private readonly IUserBegoodatService userBegoodatService;
        private readonly IUserDesignToolService userDesignToolService;
        private readonly IDesignToolService designToolService;
        private readonly IWorkHistoryService workHistoryService;
        private readonly IWebHostEnvironment env;
        private readonly IMapper mapper;

        public UserController(
            IConfiguration configuration,
            IWebUserService userService,
            IUserBegoodatService userBegoodatService,
            IUserDesignToolService userDesignToolService,
            IDesignToolService designToolService,
            IWorkHistoryService workHistoryService,
            IWebHostEnvironment env,
            IMapper mapper)
        {
            this.configuration = configuration;
            this.userService = userService;
            this.userBegoodatService = userBegoodatService;
            this.userDesignToolService = userDesignToolService;
            this.designToolService = designToolService;
            this.workHistoryService = workHistoryService;
            this.env = env;
            this.mapper = mapper;
        }

        /// <summary>
        /// 根据id查询信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}",Name ="GetById")]
        public async Task<ActionResult<UserDto>> Get(Guid id)
        {
            var emp = await userService.GetUserDtoAsync(id);
            if (emp == null)
                return NotFound();
            return Ok(emp);
        }

        /// <summary>
        /// 手机号是否已经存在
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet("exists/{phone}")]
        public async Task<ActionResult<bool>> Exists(string phone)
        {
            return await userService.ExistsAsync(u => u.Phone == phone);
        }

        /// <summary>
        /// 注册
        /// </summary>
        /// <param name="emp"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("register")]
        public async Task<IActionResult> Register(UserPost emp)
        {
            // 如果是生产环境，则验证码生效
            if (env.IsProduction())
            {
                // 验证短信验证码
                if (emp.ValidateCode != HttpContext.Session.GetString(emp.Phone))
                {
                    return BadRequest("验证码错误！");
                }
            }

            if (await userService.ExistsAsync(u=>u.Phone==emp.Phone))
            {
                return BadRequest("手机号已存在！");
            }

            emp.LoginPwd = Md5Code.MD5(emp.LoginPwd); // 密码加密
            var user = mapper.Map<WebUser>(emp);

            await userService.AddAsync(user); // 用户提交后获取用户id
           
            if (emp.Products.Count > 0)
            {
                await userBegoodatService.SetBegoodatAsync(user.Id, emp.Products); // 保存擅长项目
            }
            // 如果选择了其它工具
            if (!string.IsNullOrEmpty(emp.ToolName))
            {
                var tool = new DesignTool() { Title = emp.ToolName, Order = 20 };
                await  designToolService.AddAsync(tool );
                emp.Tools.Add(tool.Id); // 将新工具id存入id集合
            }
            // 设置生成工具
            if (emp.Tools.Count>0)
            {
                await userDesignToolService.SetDesignToolsAsync(user.Id, emp.Tools);
            }
            return Ok(new { id = user.Id });
         
        }

        /// <summary>
        /// 用户登录
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("login")]
        public async Task<IActionResult> Login(UserLogin user)
        {
            var currUser = await userService.CheckIdentity(user.Phone, Md5Code.MD5(user.Password));
            if (currUser==null)
            {
                return BadRequest("账号或密码错误");
            }
            // 生成token
            var token = new JwtHelper(configuration).GetToken(
                new TokenDTO() { 
                    Id = currUser.Id, 
                    Name = currUser.Name, 
                    Role = currUser.UserType==1?"Employee":"Employer", 
                    Phono = currUser.Phone 
                });
            return Ok(new { user = currUser, token = token });
        }

        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="id"></param>
        /// <param name="user"></param>
        /// <returns></returns>
        [HttpPatch("{id}")]
        [AllowAnonymous]
        public async Task<IActionResult> Patch(Guid id,UserPatch user)
        {
            if (id != user.Id)
                return BadRequest("用户不存在！");
            await userService.EditAsync(mapper.Map<WebUser>(user), "Name", "Address", "Sex","Age");
            return Ok("修改完成");
        }

        /// <summary>
        /// 设置头像
        /// </summary>
        /// <returns></returns>
        [HttpPatch("setImg/{id}")]
        [AllowAnonymous]
        public async Task<IActionResult> SetImg(Guid id,string imgpath)
        {
            var emp = new WebUser() { Id = id, Image = imgpath };
            await userService.EditAsync(emp, nameof(emp.Image));
            return Ok("设置完成！");
        }

        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="id">用户Id</param>
        /// <param name="oldPwd">原密码</param>
        /// <param name="newPwd">新密码</param>
        /// <returns></returns>
        [HttpPatch("setPassword/{id}")]
        public async Task<IActionResult> SetPassword(Guid id,string oldPwd,string newPwd)
        {
            var emp = await userService.GetEntityAsync(id);
            if (emp!=null && emp.LoginPwd==Md5Code.MD5(oldPwd))
            {
                emp.LoginPwd = Md5Code.MD5(newPwd);
                await userService.EditAsync(emp, nameof(emp.LoginPwd));
                return Ok("设置完成！");
            }
            else
            {
                return BadRequest();
            }
        }

        /// <summary>
        /// 重置密码
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPatch("resetPwd")]
        public async Task<IActionResult> ResetPassword(UserResetPwd data)
        {
            if (data.ValidateCode!=HttpContext.Session.GetString(data.ValidateCode))
            {
                return BadRequest("验证码错误！");
            }
            var userId = await userService.GetUserIdByPhone(data.Phone);
            var user = new WebUser() { Id = userId, LoginPwd = Md5Code.MD5(data.Password) };
            await userService.EditAsync(user, nameof(user.LoginPwd));
            return Ok("重置完成！");
        }

        /// <summary>
        /// 根据用户id获取擅长项目
        /// </summary>
        /// <param name="id">雇员Id</param>
        /// <returns></returns>
       // [Authorize(Roles ="Employee")]
        [AllowAnonymous]
        [HttpGet("{id}/begoodat")]
        public async Task<IActionResult> GetBegoodats(Guid id)
        {
            var list = await userBegoodatService.GetBegoodAts(id).Select(n => new { n.Id, n.Title }).ToListAsync();
            return Ok(list);
        }

        /// <summary>
        /// 设置雇员擅长项目
        /// </summary>
        /// <param name="id">雇员id</param>
        /// <param name="beGoodAtIds">擅长项目id集合</param>
        /// <returns></returns>
       // [Authorize(Roles = "Employee")]
        [AllowAnonymous]
        [HttpPost("{id}/Begoodat")]
        public async Task<IActionResult> SetBegoodAt(Guid id, List<Guid> beGoodAtIds)
        {
            await userBegoodatService.SetBegoodatAsync(id, beGoodAtIds);
            return Ok("设置完成！");
        }

        /// <summary>
        /// 根据用户id获取其设计工具
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpGet("{id}/designTools")]
        public async Task<IActionResult> GetDesignTools(Guid id)
        {
            var list = await userDesignToolService.GetDesignTools(id).Select(n => new { n.Id, n.Title }).ToListAsync();
            return Ok(list);
        }


        /// <summary>
        /// 设置用户使用的设计工具
        /// </summary>
        /// <param name="id">用户id</param>
        /// <param name="toolIds">设计工具id集合</param>
        /// <returns></returns>
        //[Authorize(Roles = "Employee")]
        [AllowAnonymous]
        [HttpPost("{id}/DesignTools")]
        public async Task<IActionResult> SetDesignTools(Guid id, List<Guid> toolIds)
        {
            await userDesignToolService.SetDesignToolsAsync(id, toolIds);
            return Ok("设置完成！");
        }

        /// <summary>
        /// 根据用户id获取工作经历
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}/workHistorys")]
        public async Task<IActionResult> GetWorkHistorys(Guid id)
        {
            var list = await workHistoryService.GetList(n => n.UserId == id)
                .Select(h => new { h.Id, h.BeginDate, h.EndDate, h.Content })
                .ToListAsync();
            return Ok(list);
                    
        }

        /// <summary>
        /// 分页查询雇员信息
        /// </summary>
        /// <param name="phone">手机号</param>
        /// <param name="name">姓名</param>
        /// <param name="pageIndex">页码</param>
        /// <param name="pageSize">每页数量</param>
        /// <param name="type">每页数量</param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetList(int type=-1,string phone="",string name="",int pageIndex=1,int pageSize=8)
        {
            int total = 0;
            Expression<Func<WebUser, bool>> expr;
            if (type == -1)
            {
                expr = q => q.Phone.Contains(phone) && q.Name.Contains(name);
            }
            else
                expr = q => q.Phone.Contains(phone) && q.Name.Contains(name) && q.UserType == type;


            var list = await userService.GetList(expr, pageSize, pageIndex, out total, u => u.CreateAt, false)
                .Select(n => new { n.Id, n.Name, n.Phone, n.Sex, n.Age,n.Image,n.UserType, createAt= n.CreateAt.Value.ToString("yyyy-MM-dd"),
                    beGoodAt=n.UserBegoodatRelation.Select(b=>b.BeGoodAt.Title) })
                .ToListAsync();
            return Ok(new { users = list, total = total });
                
        }

        /// <summary>
        /// 设置用户身份
        /// </summary>
        /// <param name="id">用户Id</param>
        /// <param name="userType">身份码</param>
        /// <returns></returns>
        [HttpPatch("{id}/setRole")]
        public async Task<IActionResult> SetRole(Guid id, int userType)
        {
            WebUser user = new WebUser() { Id = id, UserType = userType };
            await userService.EditAsync(user, "UserType");
            return Ok("设置完成！");
        }
    }
}
